package com.bbbug.coree.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bbbug.coree.entity.Userinfo;
import com.bbbug.coree.service.UserinfoService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@Component
public class Thirdlogin {
    private UserinfoService userinfoService;
    @Value("${myweb-path}")
    private String myweb_path;
    @Value("${third.gitee.client_id}")
    private String gitee_client_id;
    @Value("${third.gitee.client_secret}")
    private String gitee_client_secret;
    @Value("${third.ding.accessKey}")
    private String ding_accessKey;
    @Value("${third.ding.appSecret}")
    private String ding_appSecret;
    @Value("${third.oschina.client_secret}")
    private String oschina_client_secret;
    @Value("${third.oschina.client_id}")
    private String oschina_client_id;

    private String qq_client_id;

    public Thirdlogin() {
        this.userinfoService = SpringUtils.getBean(UserinfoService.class);
    }

    public Userinfo loginbyplat(String code, String plat) {
        switch (plat) {
            case "qq": {
                JSONObject myinfo = getinfoinoqq(code);
                String x = "qq";
                Userinfo userinfo = userinfoService.queryBythrid(x);
                if (userinfo == null || userinfo.equals(null)) {
                    register(myinfo.get("nickname").toString(), myinfo.get("figureurl").toString(), x);
                    userinfo = userinfoService.queryBythrid(x);
                }
                return userinfo;
            }
            case "gitee": {
                JSONObject myinfo = getinfoingitee(code);
                String x = "gitee" + myinfo.get("id");
                Userinfo userinfo = userinfoService.queryBythrid(x);
                if (userinfo == null || userinfo.equals(null)) {
                    register(myinfo.get("name").toString(), myinfo.get("avatar_url").toString(), x);
                    userinfo = userinfoService.queryBythrid(x);
                }
                return userinfo;
            }
            case "oschina": {
                JSONObject myinfo = getinfoinoschina(code);
                String x = "oschina" + myinfo.get("id");
                Userinfo userinfo = userinfoService.queryBythrid(x);
                if (userinfo == null || userinfo.equals(null)) {
                    register(myinfo.get("name").toString(), myinfo.get("avatar").toString(), x);
                    userinfo = userinfoService.queryBythrid(x);
                }
                return userinfo;
            }
            case "ding": {
                JSONObject myinfo = getinfoinding(code);
                String x = "ding" + myinfo.get("openid");
                Userinfo userinfo = userinfoService.queryBythrid(x);
                if (userinfo == null || userinfo.equals(null)) {
                    register(myinfo.get("nick").toString(), "https://dss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/tam-ogel/4c425dfb0b604ccc2ab180a0c4a595d9_121_121.jpg", x);
                    userinfo = userinfoService.queryBythrid(x);
                }
                return userinfo;
            }
        }
        return null;
    }

    JSONObject getinfoingitee(String code) {
        String url = "https://gitee.com/oauth/token?grant_type=authorization_code&code=" + code + "&client_id=" + gitee_client_id + "&redirect_uri=" + myweb_path + "/gitee&client_secret=" + gitee_client_secret;
        Map<String, Object> mp = new HashMap();
        mp.put("call_back", myweb_path + "gitee");
        mp.put("client_id", gitee_client_id);
        mp.put("code", code);
        mp.put("client_secret", gitee_client_secret);

        JSONObject body = JSONObject.parseObject(HttpUtil.createPost(url).form(mp).execute().body());

        Object access_token = body.get("access_token");
        url = "https://gitee.com/api/v5/user?access_token=" + access_token;
        mp.put("access_token", access_token);

        return JSONObject.parseObject(HttpUtil.createGet(url).execute().body());
    }

    JSONObject getinfoinding(String code) {
        String timestamp = System.currentTimeMillis() + "";
        String sign = dingdingsignature(timestamp);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tmp_auth_code", code);
        String body = HttpUtil.createGet("https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=" + ding_accessKey + "&timestamp=" + timestamp + "&signature=" + sign).header("Content-Type", "application/json").body(jsonObject.toJSONString()).execute().body();
        return JSONObject.parseObject(body).getJSONObject("user_info");
    }

    String dingdingsignature(String timestamp) {
        try {
            String appSecret = ding_appSecret;
            String stringToSign = timestamp;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8"));

            String signature = Base64.encode(signatureBytes);
            if ("".equals(signature)) {
                return "";
            }
            String encoded = URLEncoder.encode(signature, "UTF-8");
            return encoded;
            //return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    JSONObject getinfoinoschina(String code) {
        HashMap<String, Object> mp = new HashMap<>();
        mp.put("client_id", oschina_client_id);
        mp.put("client_secret", oschina_client_secret);
        mp.put("redirect_uri", myweb_path + "/oschina");
        mp.put("code", code);
        mp.put("dataType", "json");
        mp.put("grant_type", "authorization_code");
        JSONObject jsonObject = JSON.parseObject(HttpUtil.createPost("https://www.oschina.net/action/openapi/token").form(mp).execute().body());
        mp.clear();
        mp.put("access_token", jsonObject.getString("access_token"));
        mp.put("dataType", "json");
        jsonObject = jsonObject.parseObject(HttpUtil.createPost("https://www.oschina.net/action/openapi/user").form(mp).execute().body());
        return jsonObject;
    }

    JSONObject getinfoinoqq(String code) {
        JSONObject openid = JSONObject.parseObject(HttpUtil.createGet("https://graph.qq.com/oauth2.0/me?access_token=" + code).execute().body());
        openid = JSONObject.parseObject(HttpUtil.createGet("https://graph.qq.com/user/get_user_info?access_token=" + code + "&oauth_consumer_key=" + qq_client_id + "&openid=" + openid.getString("openid")).execute().body());
        return openid;
    }

    public boolean register(String user, String User_head, String user_platid) {
        Userinfo userinfo = new Userinfo();
        userinfo.setUser_account(user);
        userinfo.setUser_passwd(RandomUtil.randomString(6));
        userinfo.setUser_name(user);
        userinfo.setUser_sex(0);
        userinfo.setUser_head(User_head);
        userinfo.setUser_touchtip("头");
        userinfo.setAppname(user_platid);
        return userinfoService.insert(userinfo);
    }
}
